package com.dizner.dimagepicker;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.loader.app.LoaderManager;
import androidx.loader.content.CursorLoader;
import androidx.loader.content.Loader;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.PersistableBundle;
import android.os.SystemClock;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.dizner.dimagepicker.loader.GlideImageLoader;
import com.google.android.material.bottomsheet.BottomSheetDialog;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.TreeMap;
import java.util.TreeSet;

public class MainPickerActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Cursor>, DImageListAdapter.OnPickFinishedCallback {

    private GridView mGvListView;
    private Button mBtnConfirm;
    private ImageView mBtnCancel;
    private TextView mTvDirName;
    private DImageListAdapter mImageListAdapter;
    private LoaderManager loaderManager;
    private int mLoaderId = 10;

    private List<Image> mDataList;

    private static TreeMap<String, List<Image>> resultDataMap;

    private int mMax = 1;

    private final String M_NAME_LOADER = "loaderId";
    static final String RESULT_DATA_ID = "result_data_id";

    private TreeMap<ImageDir, TreeSet<Integer>> mImageDirMap;

    private ImageDir[] mImageDirArray;

    private int mCurrentDirIndex = 0;

    @Override

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main_picker);
        mMax = getIntent().getIntExtra("max", 1);
        initView();
        initData();
        loadDataAsync(savedInstanceState);
    }

    private void initData() {
        mImageListAdapter = new DImageListAdapter(this, new GlideImageLoader(), this);
        mImageListAdapter.setMax(mMax);
        mImageListAdapter.setSignale(false);
        mGvListView.setAdapter(mImageListAdapter);
    }

    private void loadDataAsync(Bundle bundle) {
        if (loaderManager == null) {
            loaderManager = LoaderManager.getInstance(this);
            loaderManager.initLoader(mLoaderId, bundle, this);
        } else {
            loaderManager.restartLoader(mLoaderId, bundle, this);
        }
    }

    private void initView() {
        mGvListView = findViewById(R.id.gv_image_list);
        mBtnConfirm = findViewById(R.id.btn_confirm);
        mBtnCancel = findViewById(R.id.btn_back);
        mTvDirName = findViewById(R.id.tv_dir_name);
        mBtnCancel.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onBackPressed();
            }
        });
        mBtnConfirm.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent();
                String resultId = String.valueOf(SystemClock.elapsedRealtimeNanos());
                intent.putExtra(RESULT_DATA_ID, resultId);
                if (resultDataMap == null) {
                    resultDataMap = new TreeMap<>();
                }
                List<Image> result = mImageListAdapter.getSelectionList();
                resultDataMap.put(resultId, result);
                setResult(RESULT_OK, intent);
                finish();
            }
        });
        mBtnConfirm.setEnabled(false);

        findViewById(R.id.ll_dir_name).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showSelectDialog(mImageDirArray);
            }
        });
    }

    @NonNull
    @Override
    public Loader<Cursor> onCreateLoader(int id, @Nullable Bundle args) {
        return new CursorLoader(this, MediaStore.Images.Media.EXTERNAL_CONTENT_URI, new String[]{
                MediaStore.MediaColumns._ID,
                MediaStore.Images.Media.DATA,
                MediaStore.MediaColumns.MIME_TYPE}, null, null, MediaStore.Images.Media.DEFAULT_SORT_ORDER);
    }

    @Override
    public void onLoadFinished(@NonNull Loader<Cursor> loader, Cursor data) {
        if (mDataList == null) {
            mDataList = new ArrayList<>();
        }
        mDataList.clear();
        if (!data.moveToFirst()) {
            return;
        }

        TreeSet<ImageDir> dirSet = new TreeSet<>();
        TreeSet<Integer> allSet = new TreeSet<>();
//        dirSet.add("/all");

        ImageDir allDir = ImageDir.getAImageDirBean("//");
        while (data.moveToNext()) {
            int id = data.getInt(data.getColumnIndex(MediaStore.MediaColumns._ID));
            String path = data.getString(data.getColumnIndex(MediaStore.Images.Media.DATA));
            ImageDir dir = ImageDir.getAImageDirBean(path);
//            String dir = getImageDir(path);
            if (mImageDirMap == null) {
                mImageDirMap = new TreeMap<>();
            }

            TreeSet<Integer> treeSet = mImageDirMap.get(dir);
            if (treeSet == null) {
                treeSet = new TreeSet<>();
            }
            treeSet.add(id);
            allSet.add(id);
            mImageDirMap.put(dir, treeSet);

            dirSet.add(dir);
        }
        mImageDirMap.put(allDir, allSet);
        dirSet.add(allDir);
        mImageDirArray = new ImageDir[dirSet.size()];
        dirSet.toArray(mImageDirArray);
        updateDatas();
    }

    private void updateDatas() {
        ImageDir dir = mImageDirArray[mCurrentDirIndex];
        if (dir == null) {
            return;
        }
        mTvDirName.setText(dir.getDirName());
        TreeSet<Integer> treeSet = mImageDirMap.get(dir);

        List<Image> dataList = new ArrayList<>();
        if (treeSet != null) {
            for (Integer id : treeSet) {
                Uri baseUri = Uri.parse("content://media/external/images/media");
                dataList.add(new Image(Uri.withAppendedPath(baseUri, "" + id), null));
            }
        }
        mImageListAdapter.setData(dataList);

    }

    private String getImageDir(String path) {
        int index = path.lastIndexOf(File.separator);
        return path.substring(0, index);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (loaderManager != null) {
            loaderManager.destroyLoader(mLoaderId);
        }
    }

    @Override
    public void onLoaderReset(@NonNull Loader<Cursor> loader) {

    }

    @Override
    public void onPickFinished(List<Image> result) {
        showToast(result.size() + "");
    }

    @Override
    public void onPick(List<Image> result) {

        if (result.size() >= mMax) {
            mBtnConfirm.setEnabled(true);
        } else {
            mBtnConfirm.setEnabled(false);
        }

    }

    private void showToast(String msg) {
        Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
    }

    static List<Image> outResult(String resultId) {
        List<Image> result = new ArrayList<>();
        if (!TextUtils.isEmpty(resultId)) {
            List<Image> images = resultDataMap.get(resultId);
            if (images != null) {
                result.addAll(images);
            }
        }
        return result;
    }


    private void showSelectDialog(ImageDir[] dirArray) {

        final BottomSheetDialog dialog = new BottomSheetDialog(this);
        dialog.setContentView(R.layout.dialog_images_dir_list);

        RecyclerView listView = dialog.findViewById(R.id.rlv_images_dir_list);
        ImagesDirListAdapter dirListAdapter = new ImagesDirListAdapter(this);
        listView.setLayoutManager(new LinearLayoutManager(this));
        listView.setAdapter(dirListAdapter);
        dirListAdapter.setDataList(Arrays.asList(dirArray));
        dirListAdapter.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                mCurrentDirIndex = position;
                updateDatas();
                dialog.dismiss();
            }
        });
        dialog.show();
    }
}
